package top.jnaw.jee.utils;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.kit.StrKit;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.Record;
import java.util.List;
import top.jnaw.jee.platform.Consts;
import top.jnaw.jee.platform.Consts.ModelResultType;
import top.jnaw.jee.platform.Consts.Result;

public class ModelResult {

  private Object object;
  private String message;
  private Result result;

  private ModelResultType type = ModelResultType.kNormal;

  public ModelResult() {
    object = null;
    message = null;
    result = Result.kModelError;
  }

  public ModelResult(Result result) {
    object = null;
    message = null;
    this.result = result;
  }

  public ModelResult(String message) {
    this.message = message;
    this.result = Result.kSuccess;
  }

  public void set(ModelResult r) {
    if (null != r) {
      object = r.object;
      message = r.message;
      result = r.result;
    } else {
      object = null;
      message = null;
      result = Result.kNull;
    }
  }

  public void setType(ModelResultType type) {
    this.type = type;
  }

  public Object getObject() {
    return object;
  }

  public void setObject(Object object) {
    this.object = object;
  }

  public String getMessage() {
    return message;
  }

  public void setMessage(String message) {
    this.message = message;
  }

  public Result getResult() {
    return result;
  }

  public void setResult(Result result) {
    this.result = result;
  }

  public void check() throws Exception {
    if (Result.kSuccess != result) {
      throw new Exception(message);
    }
  }

  public void check(String message) throws Exception {
    if (Result.kSuccess != result) {
      throw new Exception(message);
    }
  }

  public boolean error() {
    return Result.kSuccess != result;
  }

  public boolean fine() {
    return Result.kSuccess == result;
  }

  public String toJsonWithDateTime() {
    return Strings.formatJsonDateTime(toJson(false));
  }

  public String toJsonWithDateTime(boolean compress) {
    return Strings.formatJsonDateTime(toJson(compress));
  }

  public String toJsonWithDate() {
    return Strings.formatJsonDate(toJson(false));
  }

  public String toJsonWithDate(boolean compress) {
    return Strings.formatJsonDate(toJson(compress));
  }

  public JSONObject toJson() {
    return toJson(false);
  }

  public JSONObject toJsonId() {
    JSONObject json;

    if (object instanceof Model) {
      json = Models.toJsonId((Model) object, result);
    } else if (object instanceof Record) {
      json = Models.toJsonId((Record) object, result);
    } else {
      json = Models.toJson(result);
    }

    Log.d(Strings.formatJsonDate(json));
    return json;
  }

  public JSONObject toJson(boolean compress) {
    JSONObject json = null;

    if (Result.kSuccess == result && null != object) {
      if (object instanceof List) {
        json = Models.toJson((List) object, compress, Result.kSuccess);

        if (!json.containsKey(Consts.JSON_RES_DATA)) {
          json.put(Consts.JSON_RES_DATA, Consts.EMPTY_ARRAY);
        }
      } else if (object instanceof Page) {
        json = Models.compressPage((Page) object);

        if (!json.containsKey(Consts.JSON_RES_DATA)) {
          json.put(Consts.JSON_RES_DATA, Consts.EMPTY_ARRAY);
        }

      } else if (object instanceof Model) {
        if (compress) {
          json = Models.toJsonObject(Models.compress(object), result);
        } else {
          Object o = JSONObject.parseObject(((Model) object).toJson());
          json = Models.toJsonObject(o, Result.kSuccess);
        }

        if (!json.containsKey(Consts.JSON_RES_DATA)) {
          json.put(Consts.JSON_RES_DATA, Consts.EMPTY_OBJECT);
        }

      } else if (object instanceof Record) {
        if (compress) {
          json = Models.toJsonObject(Models.compress(object), result);
        } else {
          Object o = ((Record) object).getColumns();
          json = Models.toJsonObject(o, Result.kSuccess);
        }

        if (!json.containsKey(Consts.JSON_RES_DATA)) {
          json.put(Consts.JSON_RES_DATA, Consts.EMPTY_OBJECT);
        }

      } else {
        json = Models.toJsonObject(object, Result.kSuccess);
      }
    }

    if (null == json) {
      if (StrKit.notBlank(message)) {
        json = Models.toJson(result, message);
      } else if (fine()) {
        json = Models.toJson(result, type);
      } else {
        json = Models.toJson(result);
      }
    }

    Log.d(Strings.formatJsonDate(json));
    return json;
  }

}
